package com.github.cyf.service.impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.cyf.common.module.exception.BizException;
import com.github.cyf.common.module.response.ResponseCodeEnum;
import com.github.cyf.common.util.AESUtil;
import com.github.cyf.config.properties.LoginProperties;
import com.github.cyf.domain.po.Permission;
import com.github.cyf.domain.po.Role;
import com.github.cyf.domain.po.User;
import com.github.cyf.domain.vo.LoginVo;
import com.github.cyf.mapper.UserMapper;
import com.github.cyf.service.PermissionService;
import com.github.cyf.service.RoleService;
import com.github.cyf.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author chenyifan
 * @since 2024-10-16
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserService userService;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private LoginProperties loginProperties;

    @Override
    public String login(LoginVo vo) {
        String encryptPassword;
        try {
            encryptPassword = AESUtil.encrypt(vo.getPassword(), loginProperties.getAesKey(), loginProperties.getAesIv());
        } catch (Exception e) {
            throw new BizException(ResponseCodeEnum.ENCRYPT_ERROR, e);
        }

        User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserName, vo.getUserName()).eq(User::getPassword, encryptPassword));
        if (user == null) {
            throw new BizException(ResponseCodeEnum.LOGIN_USER_INFO_CHECK);
        }
        if (user.getEnable() == 0) {
            throw new BizException(ResponseCodeEnum.LOGIN_USER_NOT_ENABLE);
        }
        Long userId = user.getId();
        List<Role> roles = roleService.queryRoleByUserId(userId);
        if (CollectionUtils.isEmpty(roles)) {
            throw new BizException(ResponseCodeEnum.LOGIN_USER_INFO_CHECK, "用户无角色信息");
        }
        List<Long> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList());
        List<Permission> permissions = permissionService.queryPermissionByRoleIds(roleIds);
        if (CollectionUtils.isEmpty(permissions)) {
            throw new BizException(ResponseCodeEnum.LOGIN_USER_INFO_CHECK, "用户无权限信息");
        }

        // 标记当前会话登录的账号id，为这个账号创建了一个 Token 凭证
        StpUtil.login(userId);
        StpUtil.getSession().set(SaSession.USER, user);
        List<String> roleCodes = roles.stream().map(Role::getRoleCode).collect(Collectors.toList());
        List<String> permissionCodes = permissions.stream().map(Permission::getPermissionValue).collect(Collectors.toList());
        StpUtil.getSession().set(SaSession.ROLE_LIST, roleCodes);
        StpUtil.getSession().set(SaSession.PERMISSION_LIST, permissionCodes);

        // 更新最后登录时间
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, user.getId()).set(User::getLastLoginTime, LocalDateTime.now());
        userService.update(
                new LambdaUpdateWrapper<User>().eq(User::getId, user.getId()).set(User::getLastLoginTime, LocalDateTime.now())
        );
        return StpUtil.getTokenInfo().getTokenValue();
    }
}